#include "ResourcePool.h"
#include "Mesh.h"
#include "Texture.h"
#include "ResourcePtr.h"


namespace Display
{
	ResourcePool::ResourcePool(void) : DeviceUserBase()
	{

	}


	ResourcePool::~ResourcePool(void)
	{
		FreePool();
	}

	ResourcePool * ResourcePool::Create(ID3D11Device * device)
	{
		ResourcePool * pool = new ResourcePool();
		pool->SetDevice(device);

		return pool;

	}

	void ResourcePool::Destroy(ResourcePool * pool)
	{
		if(pool != nullptr)
		{
			delete pool;
			pool = nullptr;
		}
	}



	ResourcePtr * ResourcePool::AllocateMesh(std::string id)
	{
		for(itMeshes = meshes.begin();itMeshes != meshes.end();++itMeshes)
		{
			if((*itMeshes)->id == id)
			{
				ResourcePtr * ptr = new ResourcePtr((*itMeshes)->mesh);
				return ptr;
			}
		}

		Mesh * mesh = Mesh::Create(GetDevice(),this);
		Mesh_ID_Pair * pair = new Mesh_ID_Pair();
		pair->id = id;
		pair->mesh = mesh;

		meshes.push_back(pair);

		ResourcePtr * ptr = new ResourcePtr(mesh);

		return ptr;
	}


	ResourcePtr * ResourcePool::AllocateTexture(std::string id)
	{
		for(itTextures = textures.begin();itTextures != textures.end();++itTextures)
		{
			if((*itTextures)->id == id)
			{
				ResourcePtr * ptr = new ResourcePtr((*itTextures)->texture);
				return ptr;
			}
		}


		Texture * tex = Texture::Create(GetDevice(),this);
		Texture_ID_Pair * pair = new Texture_ID_Pair();
		pair->id = id;
		pair->texture = tex;

		textures.push_back(pair);

		ResourcePtr * ptr = new ResourcePtr(tex);
		return ptr;
	}

	void ResourcePool::FreePool()
	{
		ReleaseAllMeshes();
		ReleaseAllTextures();
	}

	void ResourcePool::DeAllocateMesh( Mesh * resource )
	{
		for(itMeshes = meshes.begin();itMeshes != meshes.end();++itMeshes)
		{
			if((*itMeshes)->mesh == resource)
			{
				delete (*itMeshes)->mesh;
				delete (*itMeshes);

				meshes.erase(itMeshes);
				break;
			}
		}
	}

	void ResourcePool::DeAllocateTexture( Texture * resource )
	{
		for(itTextures = textures.begin();itTextures != textures.end();++itTextures)
		{
			if((*itTextures)->texture == resource)
			{
				delete (*itTextures)->texture;
				delete (*itTextures);

				textures.erase(itTextures);
				break;
			}
		}
	}

	bool ResourcePool::MeshExist( std::string id )
	{
		for(itMeshes = meshes.begin();itMeshes != meshes.end();++itMeshes)
		{
			if((*itMeshes)->id == id)
			{
				return true;
			}
		}

		return false;
	}

	bool ResourcePool::TextureExist( std::string id )
	{
		for(itTextures = textures.begin();itTextures != textures.end();++itTextures)
		{
			if((*itTextures)->id == id)
			{
				return true;
			}
		}

		return false;
	}

	void ResourcePool::ReleaseAllMeshes()
	{
		for(itTextures = textures.begin();itTextures != textures.end();++itTextures)
		{
			delete (*itTextures)->texture;
			delete (*itTextures);
		}	

		meshes.clear();
	}

	void ResourcePool::ReleaseAllTextures()
	{
		for(itTextures = textures.begin();itTextures != textures.end();++itTextures)
		{
			delete (*itTextures)->texture;
			delete (*itTextures);
		}

		textures.clear();
	}

}